﻿namespace ClassyBlog.Web
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Mvc;

    using DataAccess;
    using DomainObjects;
    using Infrastructure;

    public class PostsController : ApplicationController
    {
        public PostsController(IPostRepository repository)
        {
            if (repository == null)
            {
                throw new ArgumentNullException("repository");
            }

            Repository = repository;
        }

        protected IPostRepository Repository { get; private set; }

        public ActionResult Index(int page, ArchivedDates archivedDates)
        {
            int total;
            IEnumerable<Post> posts;

            if (archivedDates == null || archivedDates.IsEmpty)
            {
                total = Repository.Count();
                posts = Repository.All();
            }
            else
            {
                total = Repository.Count(
                    archivedDates.StartAt, archivedDates.EndAt);

                posts = Repository.FindAll(
                    archivedDates.StartAt, archivedDates.EndAt);
            }

            var pageSize = Blog.PostsPerPage;

            posts = posts.OrderByDescending(p => p.PublishedAt)
                         .Skip(Pagination.StartIndex(page, pageSize))
                         .Take(pageSize)
                         .ToList();

            if (!posts.Any())
            {
                return HttpNotFound();
            }

            var model = new ArchivedPostList(
                page, total, pageSize, posts, archivedDates);

            return View(model);
        }

        public ActionResult Tagged(int page, string slug)
        {
            var total = Repository.Count(slug);

            var pageSize = Blog.PostsPerPage;

            var posts = Repository.FindAll(slug)
                                  .OrderByDescending(p => p.PublishedAt)
                                  .Skip(Pagination.StartIndex(page, pageSize))
                                  .Take(pageSize)
                                  .ToList();

            if (!posts.Any())
            {
                return HttpNotFound();
            }

            var tag = posts.SelectMany(p => p.Tags)
                           .FirstOrDefault(t =>
                               t.Slug.Equals(
                               slug, StringComparison.OrdinalIgnoreCase));

            var model = new TaggedPostList(page, total, pageSize, posts, tag);

            return View(model);
        }

        public ActionResult Show(string slug)
        {
            var post = Repository.FindOne(slug);

            var result = (post == null) ||
                         (post.PublishedAt >= Clock.UtcNow()) ?
                         HttpNotFound() as ActionResult :
                         View(new ItemModel<Post>(post));

            return result;
        }
    }
}